﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace MDrive.ViewModels
{
    public class PhysicsModel : ViewModelBase
    {
        public PhysicsModel(ComViewModel comViewModel)
        {
            _comViewModel = comViewModel;
            Start = new RelayCommand(OnStart);
            Return = new RelayCommand(OnReturn);
            Stop = new RelayCommand(OnStop);
            PullyDiameterMm = 14.08;
            TotalDistanceM = 1;
            AccelerationMss = 1;
            MaximumVelocityMs = 1;
            DecelerationMss = 1;
        }

        private double _pullyDiameterMm;
        public double PullyDiameterMm
        {
            get { return _pullyDiameterMm; }
            set { SetProperty(ref _pullyDiameterMm, Math.Abs(value)); }
        }

        private double _totalDistanceM;
        public double TotalDistanceM
        {
            get { return _totalDistanceM; }
            set { SetProperty(ref _totalDistanceM, Math.Abs(value)); }
        }

        private double _accelerationMss;
        public double AccelerationMss
        {
            get { return _accelerationMss; }
            set { SetProperty(ref _accelerationMss, Math.Abs(value)); }
        }

        private double _maximumVelocityMs;
        public double MaximumVelocityMs
        {
            get { return _maximumVelocityMs; }
            set { SetProperty(ref _maximumVelocityMs, Math.Abs(value)); }
        }

        private double _decelerationMss;
        public double DecelerationMss
        {
            get { return _decelerationMss; }
            set { SetProperty(ref _decelerationMss, Math.Abs(value) * -1); }
        }

        public RelayCommand Start { get; private set; }
        public RelayCommand Return { get; private set; }
        public RelayCommand Stop { get; private set; }

        void OnStart()
        {
            var metersPerStep = (PullyDiameterMm / 1000) * Math.PI / 2048;
            var moveTo = (int)Math.Round(TotalDistanceM / metersPerStep);
            var acceleration = (int)Math.Round(AccelerationMss / metersPerStep);
            var deceleration = (int)Math.Round(DecelerationMss * -1 / metersPerStep);
            var maximumVelocity = (int)Math.Round(MaximumVelocityMs / metersPerStep);
            SendNow("VM=" + maximumVelocity);
            SendNow("A=" + acceleration);
            SendNow("D=" + deceleration);
            SendNow("MR " + moveTo);
        }

        void OnReturn()
        {
            var metersPerStep = (PullyDiameterMm / 1000) * Math.PI / 2048;
            var moveTo = (int)Math.Round(TotalDistanceM * -1 / metersPerStep);
            var acceleration = (int)Math.Round(AccelerationMss / metersPerStep);
            var deceleration = (int)Math.Round(DecelerationMss * -1 / metersPerStep);
            var maximumVelocity = (int)Math.Round(MaximumVelocityMs / metersPerStep);
            SendNow("VM=" + maximumVelocity);
            SendNow("A=" + acceleration);
            SendNow("D=" + deceleration);
            SendNow("MR " + moveTo);
        }

        void OnStop()
        {
            SendNow("D=1000000");
            SendNow("SL 0");
            SendNow("ER 0");
            SendNow("EE=1");
            SendNow("P=0");
            SendNow("SF=2048");
            SendNow("HC=0");
            SendNow("VI=1");
            SendNow("RC=100");
        }

        void SendNow(String command)
        {
            Debug.WriteLine(command);
            _comViewModel.EnQueue(command);
        }

        ComViewModel _comViewModel;
    }
}
